<template>
  <div style="width: 100%">
    <div class="search-box">
      <el-select
        v-model="address"
        clearable
        placeholder="请输入位置关键词"
        style="width: 240px"
        :remote-method="remoteMethod"
        filterable
        remote
        @change="currentSelect"
        class="one-text"
        size="default"
      >
        <el-option
          v-for="(item, index) in areaList"
          :key="index"
          :label="item.district + item.name"
          :value="item.district + item.name"
        >
          <span>{{ item.district }}</span> <span>{{ item.name }}</span>
        </el-option>
      </el-select>

      <el-select
        v-model="coverage"
        clearable
        placeholder="请选择距离"
        style="width: 240px; margin-left: 5px"
        size="default"
        @change="getCoverageC"
      >
        <el-option
          v-for="item in distanceOption"
          :key="item.id"
          :label="item.name"
          :value="item.id"
        >
          <span>{{ item.district }}</span> <span>{{ item.name }}</span>
        </el-option>
      </el-select>

      <!-- <el-button type="success" v-if="addressGet" class="address">{{
          addressGet.split(",")[0]
        }}</el-button> -->
    </div>
    <div id="container" class="map"></div>
  </div>
</template>

<script setup>
import {
  reactive,
  ref,
  toRefs,
  onMounted,
  nextTick,
  defineProps,
  defineEmits,
} from "vue";
import AMapLoader from "@amap/amap-jsapi-loader";
// 定义 props 和 emits
const emits = defineEmits(["address", "get-coverage"]);
const props = defineProps({
  addressClick: Function,
});
onMounted(() => {
  window._AMapSecurityConfig = {
    securityJsCode: "你的安全密钥", // https://console.amap.com/dev/key/app   绑定的服务为 Web端
  };
  initMap();
});
const addressGet = ref("");
const coverage = ref(null);
const distanceOption = [
  {
    id: 100,
    name: "100米",
  },
  {
    id: 200,
    name: "200米",
  },
  {
    id: 300,
    name: "300米",
  },
  {
    id: 400,
    name: "400米",
  },
];

const state = reactive({
  map: null,
  placeSearch: null,
  autoComplete: null,
  marker: null,
  form: {
    address: "",
    lng: "",
    lat: "",
  },
  areaList: [],
  address: "",
});

const { areaList, address } = toRefs(state);

const getCoverageC = () => {
  emits("get-coverage", coverage.value);
};

function initMap(arr) {
  AMapLoader.load({
    key: "67399b84761c2d0aed556b4f7f1dd39f", // https://console.amap.com/dev/key/app   绑定的服务为 Web端
    version: "2.0",
    plugins: [
      "AMap.ToolBar",
      "AMap.ControlBar",
      "AMap.AutoComplete",
      "AMap.PlaceSearch",
      "AMap.Geocoder",
      "AMap.Marker",
      "AMap.Geolocation",
    ],
  })
    .then((AMap) => {
      state.map = new AMap.Map("container", {
        viewMode: "3D", //  是否为3D地图模式
        zoom: 15,
        center: arr,
        resizeEnable: true,
        center: [104.063403, 30.568744],
      });
      // 地图放大缩小插件
      let toolBar = new AMap.ToolBar({
        position: {
          top: "120px",
          right: "51px",
        },
      });
      // 3D地图插件
      let controlBar = new AMap.ControlBar({
        position: {
          top: "20px",
          right: "20px",
        },
      });

      state.geoCoder = new AMap.Geocoder({
        city: "010", //城市设为北京，默认：“全国”
        radius: 1000, //范围，默认：500
      });

      // 正向地理编码
      state.geocoder = new AMap.Geocoder({
        city: state.address,
      });
      // 定位
      let geolocation = new AMap.Geolocation({
        enableHighAccuracy: true, // 是否使用高精度定位，默认:true
        timeout: 10000, // 超过10秒后停止定位，默认：5s
        position: {
          top: "300px",
          right: "30px",
        }, // 定位按钮的停靠位置
        buttonOffset: new AMap.Pixel(10, 20), // 定位按钮与设置的停靠位置的偏移量，默认：Pixel(10, 20)
        zoomToAccuracy: true, // 定位成功后是否自动调整地图视野到定位点
      });
      // 监听定位按钮的点击事件
      geolocation.on("complete", (result) => {
        console.log("定位成功:", result);
        // 处理定位成功的逻辑
        console.log(result.position.lng, result.position.lat);

        // 使用高德地图 JavaScript API 的坐标转换服务将 WGS84 坐标转换为 GCJ02 坐标
        AMap.convertFrom(
          [result.position.lng, result.position.lat],
          "gps",
          (status, result) => {
            if (status === "complete" && result.locations.length > 0) {
              const gcj02Lng = result.locations[0].lng;
              const gcj02Lat = result.locations[0].lat;
              // 解析定位结果为中文地址
              let lnglat = [gcj02Lng, gcj02Lat];
              console.log(gcj02Lng, gcj02Lat);
              state.geoCoder.getAddress(lnglat, (status, addressResult) => {
                if (status === "complete" && addressResult.regeocode) {
                  let formattedAddress =
                    addressResult.regeocode.formattedAddress;
                  console.log("解析后的地址:", formattedAddress);
                  // 在这里处理解析后的地址
                  addressGet.value = formattedAddress;
                  state.address = formattedAddress;

                  // 返回给父组件的值
                  emits(
                    "address",
                    `${formattedAddress},${gcj02Lng},${gcj02Lat}`
                  );
                }
              });
              // 这里可以继续处理转换后的坐标数据，例如显示标记点等
            } else {
              console.error("Coordinate conversion failed.");
            }
          }
        );
      });

      geolocation.on("error", (error) => {
        console.error("定位失败:", error);
        // 处理定位失败的逻辑
      });

      state.autoComplete = new AMap.AutoComplete({ city: "全国" });
      state.map.setDefaultCursor("pointer"); // 使用CSS默认样式定义地图上的鼠标样式
      state.map.on("click", (e) => {
        // 点击地图事件
        if (!e && !e.lnglat) {
          return;
        }
        state.form.lng = e.lnglat.lng;
        state.form.lat = e.lnglat.lat;
        removeMarker(); // 先删除地图上标记点
        setMapMarker(); // 在添加新的标记点
      });
      state.map.addControl(toolBar); // 添加右上角的放大缩小
      state.map.addControl(controlBar); // 添加右上角的放大缩小
      state.map.addControl(geolocation); // 添加右上角的放大缩小
      // 监听定位成功事件
    })
    .catch((e) => {
      console.error(e); //加载错误提示
    })
    .finally(() => {
      removeMarker();
      setMapMarker();
    });
}

function setMapMarker() {
  if (state.form.lng == "" && state.form.lat == "") {
    return;
  }
  state.map.setFitView();
  state.marker = new AMap.Marker({
    map: state.map,
    position: [state.form.lng, state.form.lat],
  });
  toGetAddress();
  state.map.setFitView();
  state.map.add(state.marker);
}

function removeMarker() {
  if (state.marker) {
    state.map.remove(state.marker);
  }
}

function toGetAddress() {
  let lnglat = [state.form.lng, state.form.lat];
  state.geoCoder.getAddress(lnglat, (status, result) => {
    if (status === "complete" && result.regeocode) {
      props.addressClick(
        result,
        state.form.lng,
        state.form.lat,
        state.form.address
      ); // 返回位置信息以及经纬度
      addressGet.value = `${result.regeocode.formattedAddress},${state.form.lng},${state.form.lat}`;
    }
  });
}

function remoteMethod(query) {
  if (query !== "") {
    setTimeout(() => {
      state.autoComplete.search(query, (status, result) => {
        state.areaList = result.tips;
      });
    }, 500);
  } else {
    state.areaList = [];
  }
}
function currentSelect(val) {
  if (!val) {
    return;
  }
  toGetCoordinate(val);
}

function toGetCoordinate(address) {
  state.geocoder.getLocation(address, function (status, result) {
    if (status === "complete" && result.info === "OK") {
      initMap([
        result.geocodes[0].location.lng,
        result.geocodes[0].location.lat,
      ]);
      state.form.lng = result.geocodes[0].location.lng;
      state.form.lat = result.geocodes[0].location.lat;
      state.form.address = `${result.geocodes[0].formattedAddress}`;

      // 返回给父组件的值
      emits(
        "address",
        `${result.geocodes[0].formattedAddress},${result.geocodes[0].location.lng},${result.geocodes[0].location.lat}`
      );
    }
  });
  nextTick(function () {
    removeMarker();
    setMapMarker();
  });
}

function fixed(lng, lat) {
  initMap([lng, lat]);
  state.form.lng = lng;
  state.form.lat = lat;
}

// 暴露方法
defineExpose({
  fixed,
  toGetCoordinate,
});
</script>

<style scoped lang="scss">
.map {
  width: 100%;
  height: 500px;
  padding-top: 20px;
}

#container {
  margin-top: 20px;
  border-radius: 5px;
}

.search-box {
  display: flex;
  // position: relative;
  // z-index: 9999 !important;
  // margin-left: 20px;
}

.address {
  margin-left: 20px;
}
</style>
